package org.performancetracker.simple;

import org.performancetracker.api.Tracker;
import org.performancetracker.api.Aggregator;
import org.performancetracker.api.Reporter;

/**
 * Basic tracker implementation.
 *
 * A basic tracker is not multithreading safe.
 * Normally this is not a problem as it mostly will be used to track single threaded taks performance.
 *
 * @author: jaronschut
 */

public class TrackerImpl implements Tracker, Reporter { 

    /* The tracker aggregator set during construction */
    private final Aggregator aggregator;

    /* The start time of the tracker set during construction */
    private Long startTime;

    /* Message set when the tracker */
    private String message;

	/* The end time */
    private Long endTime;

	/**
     * Protected constructor.
     *
     * @param aggregator
     */
    protected TrackerImpl(Aggregator aggregator) {
        this.aggregator = aggregator;
        this.startTime = System.currentTimeMillis();
    }

	/*********** TRACKER INTERFACE **************/
	/**
	 * Aggregate the tracker.
	 *
	 * typical calling is:
	 *
	 * tracker.stop().aggregate("all ok");
	 */
	public void aggregate(String message) {
		if (startTime != null && endTime != null) {
			this.message = message;
			this.aggregator.aggregate(this);
		}
	}

    /**
     * Start the timer.
     *
     * @return itself
     */
	public Tracker start() {
		if (startTime == null && endTime == null) {

			startTime = System.currentTimeMillis();
		}
		return this;
	}

    /**
     * Stop the timer.
     *
     * @return itself
     */
	public Tracker stop() {
		if (startTime != null) {

			endTime = System.currentTimeMillis();
		}
		return this;
	}

	/*********** REPORTER INTERFACE **************/
	/**
	 * Get the elapsed time.
	 *
	 * @return
	 */
	public Long getElapsedTime() {
		return new Long(startTime.longValue() - endTime.longValue());
	}

	/**
	 * Get the message to aggregate.
	 *
	 * @return
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * The start time.
	 *
	 * @return
	 */
	public Long getStartTime() {
		return startTime;
	}

	/**
	 * The end time.
	 *
	 * @return
	 */
	public Long getEndTime() {
		return endTime;
	}
}
